// SubstSvc NT service.
// Copyright (c) 2004-2007 by Elijah Zarezky,
// All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ExecLogging.cpp - implementation of the execution logging

// initially generated by AfxScratch v1.0.2290 on 18.07.2004 at 11:12:43
// visit http://zarezky.spb.ru/projects/afx_scratch.html for more info

#include "stdafx.h"
#include "ExecLogging.h"
#include "Resource.h"

#if defined(__INTEL_COMPILER)
// remark #174: expression has no effect
#pragma warning(disable: 174)
// remark #177: variable was declared but never referenced
#pragma warning(disable: 177)
// remark #593: variable was set but never used
#pragma warning(disable: 593)
// remark #981: operands are evaluated in unspecified order
#pragma warning(disable: 981)
// remark #1418: external definition with no prior declaration
#pragma warning(disable: 1418)
#endif	// __INTEL_COMPILER

#if defined(_DEBUG)
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif	// _DEBUG

// private globals
static CString g_strLogName;
static CCriticalSection g_csLogging;
static LOG_LEVEL g_eLogLevel;

// creates log file
void LogFile_Create(LPCTSTR pszFileName)
{
	CStdioFile fileLog;
	CFileException xcpt;
	CString strBegin;

	CWinApp* pApp = AfxGetApp();
	g_strLogName = pszFileName;
	UINT fuOpen = CFile::modeCreate | CFile::modeWrite | CFile::typeText;
	if (pApp->GetProfileInt(_T("Logging"), _T("Continuous"), FALSE))
	{
		fuOpen |= CFile::modeNoTruncate;
	}
	if (fileLog.Open(g_strLogName, fuOpen, &xcpt))
	{
		try
		{
			fileLog.SeekToEnd();
			strBegin.LoadString(IDS_LOG_BEGIN);
			fileLog.WriteString(strBegin);
			fileLog.Close();
		}
		catch (CFileException* pXcpt)
		{
			// simple clean-up
			pXcpt->Delete();
		}
	}
	else {
		// unable to create log file
	}
	g_eLogLevel = static_cast<LOG_LEVEL>(pApp->GetProfileInt(_T("Logging"), _T("Level"), LL_NORMAL));
}

// writes log file entry
void LogFile_WriteEntryV(LOG_LEVEL eLevel, LPCTSTR pszFormat, va_list argList)
{
	CString strTemp;
	CString strEntry;
	CStdioFile fileLog;
	CFileException xcpt;

	if (eLevel <= g_eLogLevel)
	{
		// this entry should be written
		CString strTime = CTime::GetCurrentTime().Format(_T("%d.%m.%Y %H:%M:%S"));
		strTemp.FormatV(pszFormat, argList);
		strTemp.Replace(_T("\r\n"), _T("\n"));
		strTemp.TrimRight(_T('\n'));
		strEntry.Format(_T("%s\t%s\n"), static_cast<LPCTSTR>(strTime), static_cast<LPCTSTR>(strTemp));
		CSingleLock singleLock(&g_csLogging);
		singleLock.Lock();
		if (singleLock.IsLocked())
		{
			// log file has been locked
			enum { fuOpen = CFile::modeWrite | CFile::typeText };
			if (fileLog.Open(g_strLogName, fuOpen, &xcpt))
			{
				try
				{
					fileLog.SeekToEnd();
					fileLog.WriteString(strEntry);
					fileLog.Close();
				}
				catch (CFileException* pXcpt)
				{
					// simple clean-up
					pXcpt->Delete();
				}
			}
			else {
				// unable to open log file - nothing we can do
			}
			singleLock.Unlock();
		}
	}
}

// writes log file entry
void LogFile_WriteEntry(LOG_LEVEL eLevel, LPCTSTR pszFormat, ...)
{
	va_list argList;

	va_start(argList, pszFormat);
	LogFile_WriteEntryV(eLevel, pszFormat, argList);
	va_end(argList);
}

// writes log file entry
void LogFile_WriteEntry(LOG_LEVEL eLevel, UINT idsFormat, ...)
{
	CString strFormat;
	va_list argList;

	if (strFormat.LoadString(idsFormat))
	{
		va_start(argList, idsFormat);
		LogFile_WriteEntryV(eLevel, strFormat, argList);
		va_end(argList);
	}
}

// writes DCRT report to the log file
int LogFile_WriteDbgRpt(int /*fnType*/, char* pszMessage, int* /*pnRetVal*/)
{
	USES_CONVERSION;

	CStdioFile fileLog;
	CFileException xcpt;

	if (g_eLogLevel > LL_NONE)
	{
		// some logging is enbaled
		CSingleLock singleLock(&g_csLogging);
		singleLock.Lock();
		if (singleLock.IsLocked()) {
			// log file has been locked
			enum { fuOpen = CFile::modeWrite | CFile::typeText };
			if (fileLog.Open(g_strLogName, fuOpen, &xcpt))
			{
				try
				{
					fileLog.SeekToEnd();
					CString strTemp(A2T(pszMessage));
					strTemp.Replace(_T("\r\n"), _T("\n"));
					fileLog.WriteString(strTemp);
					fileLog.Close();
				}
				catch (CFileException* pXcpt)
				{
					// simple clean-up
					pXcpt->Delete();
				}
			}
			else {
				// unable to open log file - nothing we can do
			}
			singleLock.Unlock();
		}
		// completely handled
		return (TRUE);
	}
	else {
		return (FALSE);
	}
}

// end of file
